<template>
	<view class="yingbing-read-page" ref="yingbingReadPage" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
		<view class="computed">
			<text class="computed-text computed-text-chinese" ref="computedTextChinese" :style="{
				'font-family': fontFamily
			}">中</text>
			<text class="computed-text computed-text-space" ref="computedTextSpace" :style="{
				'font-family': fontFamily
			}">s</text>
			<text class="computed-text computed-text-lower" ref="computedTextLower" :style="{
				'font-family': fontFamily
			}">a</text>
			<text class="computed-text computed-text-upper" ref="computedTextUpper" :style="{
				'font-family': fontFamily
			}">A</text>
			<text class="computed-text computed-text-number" ref="computedTextNumber" :style="{
				'font-family': fontFamily
			}">9</text>
			<text class="computed-text computed-text-special" ref="computedTextSpecial" :style="{
				'font-family': fontFamily
			}">&</text>
			<text class="computed-text computed-text-tibetan" ref="computedTextTibetan" :style="{
				'font-family': fontFamily
			}">སྤྱོ</text>
		</view>
		<!-- 翻页模式 -->
		<view class="yingbing-read-page-flip" :style="{
			'visibility': pageType != 'scroll' ? 'visible' : 'hidden'
		}">
			<yingbing-flip ref="flip" class="yingbing-read-page-flip" :data="pages" :current="current" :bgColor="bgColor" :duration="300" :unableClickPage="unableClickPage" :type="pageType" @change="handleFlipChangeRender">
				<!-- #ifdef MP -->
				<template v-for="(item, index) in pages" :slot="index">
				<!-- #endif -->
				<!-- #ifndef MP -->
				<template v-slot="{item, index}">
				<!-- #endif -->
					<view class="flip-item-wrapper" :style="{
						'padding-left': slide + 'px',
						'padding-right': slide + 'px',
						'padding-top': topGap + 'px',
						'padding-bottom': bottomGap + 'px'
					}">
						<view class="flip-item-header" v-if="headerShow">
							<text class="flip-item-header-text" :style="{
								color: color,
								'font-family': fontFamily
							}">{{item.title}}</text>
						</view>
						<template v-if="item.type == 'text'">
							<view class="flip-item-text flip-item-content"
							>
								<text class="flip-text"
								v-for="(text, i) in item.text" :key="i"
								:style="{
									'margin-top': options.lineHeight + 'px',
									'height': options.fontSize + 'px',
									'font-size': options.fontSize + 'px',
									'color': options.color,
									'font-family': options.fontFamily,
									'line-height': options.fontSize + 'px'
								}">{{text}}</text>
							</view>
						</template>
						<template v-if="item.type == 'custom'">
							<read-rich-text style="flex: 1;" :richtext="item.text" :fontFace="fontFace" :pageType="pageType" @customClick="customClick"></read-rich-text>
						</template>
						<template v-if="item.type == 'slot'">
							<view class="flip-slot flip-item-content">
								<!-- #ifndef MP-WEIXIN -->
								<slot :name="item.text" :prop="item"></slot>
								<!-- #endif -->
								<!-- #ifdef MP-WEIXIN -->
								<slot :name="item.text"></slot>
								<!-- #endif -->
							</view>
						</template>
						<template v-if="item.type == 'loading'">
							<view class="flip-loading flip-item-content">
								<text class="flip-loading-text" :style="{
									'color': options.color,
									'font-family': options.fontFamily
								}">正在加载内容</text>
							</view>
						</template>
						<template v-if="item.type == 'fail' || item.type == 'timeout' ">
							<view class="flip-loading flip-item-content">
								<text class="flip-loading-text" @tap="reloadLoadmoreFlip(item)" :style="{
									'color': options.color,
									'font-family': options.fontFamily
								}">{{item.type == 'timeout' ? '加载超时' : '加载失败'}},点击刷新</text>
							</view>
						</template>
						<template v-if="item.type == 'top' || item.type == 'bottom' ">
							<view class="flip-loading flip-item-content">
								<slot :name="item.type">
									<text class="flip-loading-text" :style="{
										'color': options.color,
										'font-family': options.fontFamily
									}">{{item.type == 'top' ? firstTip : lastTip}}</text>
								</slot>
							</view>
						</template>
						<!-- <template v-else>
							<view class="flip-loading flip-item-content">
								<text class="flip-loading-text" :style="{
									'color': options.color,
									'font-family': options.fontFamily
								}">未知类型页面</text>
							</view>
						</template> -->
						<view class="flip-item-footer" v-if="footerShow">
							<text class="flip-item-footer-text" :style="{
								color: color,
								'font-family': fontFamily
							}">{{filterDate()}}</text>
							<text class="flip-item-footer-text" :style="{
								color: color,
								'font-family': fontFamily
							}">{{filterPage(item)}}</text>
							<battery :color="color" style="opacity: 0.5"></battery>
						</view>
					</view>
				</template>
			</yingbing-flip>
		</view>
		<!-- 翻页模式 -->
		
		<!-- 滚动模式 -->
		<view
		class="yingbing-scroll"
		:style="{
			'background': options.bgColor,
			'visibility': pageType == 'scroll' ? 'visible' : 'hidden'
		}">
			<template v-if="pageType == 'scroll'">
				<view :style="{height: options.topGap + 'px'}"></view>
				<view class="flip-item-header" :style="{
					'padding-left': options.slide + 'px',
					'padding-right': options.slide + 'px'
				}" v-if="options.headerShow">
					<text class="flip-item-header-text" :style="{
						color: options.color,
						'font-family': options.fontFamily
					}">{{pageInfo.title || '加载中'}}</text>
				</view>
				<scroll-list
				ref="list"
				@scroll="onScroll"
				:pulldown="{show: true, color: options.color, defaultText: '下拉获取上一章节', endText: firstTip, failText: '获取上一章节失败'}"
				:loadmore="{show: true, color: options.color, defaultText: '上拉获取上一章节',  endText: lastTip, failText: '获取下一章节失败'}"
				@pulldown="pulldownScroll"
				@loadmore="loadmoreScroll"
				@scrolltoupper="scrolltoupper">
					<view class="scroll-item-wrapper" ref="scrollItemWrapper">
						<view
						:id="'scroll-item_' + item.dataId"
						v-for="(item, index) in pages"
						:key="item.dataId"
						class="scroll-item"
						:ref="'scrollItem_' + item.dataId"
						:style="{
							'padding-left': options.slide + 'px',
							'padding-right': options.slide + 'px'
						}">
							<template v-if="item.type == 'text'">
								<view class="scroll-item-text scroll-item-content"
								>
									<text class="scroll-text"
									v-for="(text, i) in item.text" :key="i"
									:style="{
										'margin-top': options.lineHeight + 'px',
										'height': options.fontSize + 'px',
										'font-size': options.fontSize + 'px',
										'color': options.color,
										'font-family': options.fontFamily,
										'line-height': options.fontSize + 'px'
									}">{{text}}</text>
								</view>
							</template>
							<template v-else-if="item.type == 'custom'">
								<read-rich-text :richtext="item.text" :fontFace="fontFace" :pageType="pageType" @customClick="customClick"></read-rich-text>
							</template>
							<template v-else-if="item.type == 'slot'">
								<view class="scroll-slot scroll-item-content">
									<slot :name="item.text"></slot>
								</view>
							</template>
						</view>
					</view>
					<view :style="{height: options.bottomGap + 'px'}"></view>
				</scroll-list>
				<view class="flip-item-footer" :style="{
					'padding-left': options.slide + 'px',
					'padding-right': options.slide + 'px'
				}" v-if="options.footerShow">
					<text class="flip-item-footer-text" :style="{
						color: options.color,
						'font-family': options.fontFamily
					}">{{filterDate()}}</text>
					<text class="flip-item-footer-text" :style="{
						color: options.color,
						'font-family': options.fontFamily
					}">{{filterPage(pageInfo)}}</text>
					<battery ref="scrollBattery" :color="options.color" style="opacity: 0.5"></battery>
				</view>
				<view :style="{height: options.bottomGap + 'px'}"></view>
				<!-- <view class="scroll-item-header" :style="{
					'top': options.topGap + 'px',
				}" v-if="options.headerShow">
					<text class="scroll-item-header-text" :style="{
						'font-family': options.fontFamily
					}">{{(pageInfo.title || '加载中')}}</text>
				</view>
				<view class="scroll-item-footer" :style="{
					'bottom': options.bottomGap + 'px'
				}" v-if="options.footerShow">
					<text class="scroll-item-footer-text" :style="{
						'font-family': options.fontFamily
					}">{{scrollDate}}</text>
					<text class="scroll-item-footer-text" :style="{
						'font-family': options.fontFamily
					}">{{filterPage(pageInfo)}}</text>
					<battery ref="scrollBattery" color="#fff"></battery>
				</view> -->
			</template>
		</view>
		<view class="yingbing-loading" v-if="loadstatus" :style="{background: options.bgColor}" @tap="_reload">
			<text class="error-text" :style="{
				color: options.color
			}">{{loadstatus == 'fail' ? '加载失败' : '加载超时'}},点击刷新</text>
		</view>
		<view class="yingbing-loading" v-if="initLoading" :style="{background: options.bgColor}">
			<list-loading :size="40" :visible="initLoading" :color="options.color" text="正在加载中"></list-loading>
		</view>
	</view>
</template>

<script>
	import NochapterMixin from '../modules/nochapter/nochater.js'
	import Battery from '../modules/battery.vue'
	import ReadRichText from '../modules/richtext.vue'
	import FlipMixin from '../modules/flip/flip.js'
	import ScrollMixin from '../modules/scroll/scroll.js'
	import ComputedMixin from '../modules/computed/computed.js'
	// import Computed from '../modules/computed/computed.vue'
	import ScrollList from '../modules/list/list.vue'
	import ListLoading from '../modules/list/modules/common/loading.vue'
	import Util from '../../js_sdk/util.js'
	export default {
		mixins: [FlipMixin, ScrollMixin, ComputedMixin, NochapterMixin],
		components: {
			// Computed,
			Battery,
			ReadRichText,
			ScrollList,
			ListLoading
		},
		props: {
			//自动翻页/滚动
			autoplay: {
				type: Boolean,
				default: false
			},
			//自动翻页/滚动周期
			autoplayTime: {
				type: [String, Number],
				default: 5000
			},
			//字体颜色
			color: {
				type: String,
				default: '#333333'
			},
			//字体大小（单位px）
			fontSize: {
				type: [String, Number],
				default: 15
			},
			//字体名称
			fontFamily: {
				type: String,
				default: 'Microsoft YaHei, 微软雅黑'
			},
			//第三方字体
			fontFace: {
				type: Array,
				default () {
					return new Array
				}
			},
			firstTip: {
				type: String,
				default: '前面已经没有了'
			},
			lastTip: {
				type: String,
				default: '后面已经没有了'
			},
			//关闭第一页提示
			firstTipUnable: {
				type: Boolean,
				default: false
			},
			//关闭最后一页提示
			lastTipUnable: {
				type: Boolean,
				default: false
			},
			//背景颜色
			bgColor: {
				type: String,
				default: '#fcd281'
			},
			//是否关闭点击左右2侧位置翻页
			unableClickPage: {
				type: Boolean,
				default: false
			},
			//翻页方式
			pageType: {
				type: String,
				default: 'real'
			},
			//行间距（单位px）
			lineHeight: {
				type: [Number, String],
				default: 15
			},
			//页面左右边距（单位px）
			slide: {
				type: [Number, String],
				default: 20
			},
			//页面上边距（单位px）
			topGap: {
				type: [Number, String],
				default: 10
			},
			//页面下边距（单位px）
			bottomGap: {
				type: [Number, String],
				default: 10
			},
			//开启预加载
			enablePreload: {
				type: Boolean,
				default: false
			},
			//是否开启整书模式
			noChapter: {
				type: Boolean,
				default: false
			},
			//开启点击事件
			enableClick: {
				type: Boolean,
				default: false
			},
			//展示顶部信息
			headerShow: {
				type: Boolean,
				default: true
			},
			//展示底部信息
			footerShow: {
				type: Boolean,
				default: true
			},
			//分隔符
			split: {
				type: String,
				default: ''
			},
			//点击事件位置设置
			clickOption: {
				type: Object,
				default () {
					return {
						width: uni.upx2px(200),
						height: uni.upx2px(200),
						left: 'auto',
						top: 'auto'
					}
				}
			}
		},
		data () {
			return {
				pageInfo: {
					dataId: -1
				},
				pages: [],
				contents: [],
				isClickToTouch: false,
				touchstartX: 0,
				touchstartY: 0,
				touchmoveX: 0,
				touchmoveY: 0,
				touchTime: 0,
				windowWidth: 0,
				windowHeight: 0,
				initLoading: true,
				loadstatus: '',
				loadchapter: -1,
				loadstart: -1
			}
		},
		computed: {
			Util () {
				return Util
			},
			options () {
				return {
					unableClickPage: this.unableClickPage,
					pageType: this.pageType,
					color: this.color,
					bgColor: this.bgColor,
					enablePreload: this.enablePreload,
					headerShow: this.headerShow,
					footerShow: this.footerShow,
					fontFamily: this.fontFamily,
					fontFace: this.fontFace,
					slide: this.slide > 0 ? parseInt(this.slide) : 0,
					topGap: this.topGap > 0 ? parseInt(this.topGap) : 0,
					bottomGap: this.bottomGap > 0 ? parseInt(this.bottomGap) : 0,
					fontSize: this.fontSize >= 12 ? parseInt(this.fontSize) : 12,//字体大小最小只能到12px，因为谷歌浏览器最小只支持12px
					lineHeight: this.lineHeight >= 5 ? parseInt(this.lineHeight) : 5,
				}
			}
		},
		beforeDestroy () {
			this.clearRefreshTimer()
			this.stopAutoplay()
		},
		mounted () {
			this.$nextTick(function () {
				setTimeout(() => {
					Util.getRect('.yingbing-read-page', this.$refs.yingbingReadPage, this).then(res => {
						this.windowWidth = res.width
						this.windowHeight = res.height
					})
				}, 20)
			})
			this.initFont()
		},
		methods: {
			touchstart (e) {
				this.stopAutoplay()
				if ( !this.enableClick ) {
					return
				}
				if ( this.isClickToTouch ) {
					return
				}
				this.resetTouch();
				this.touchInter = setTimeout(() => {
					this.touchTime = 300
				}, 300)
				let touch = e.touches[0]
				this.touchstartX = touch.pageX;
				this.touchstartY = touch.pageY;
			},
			touchmove (e) {
				if ( !this.enableClick ) {
					return
				}
				if ( this.isClickToTouch ) {
					return
				}
				let touch = e.touches[0]
				this.touchmoveX = touch.pageX;
				this.touchmoveY = touch.pageY;
			},
			touchend (e) {
				this.startAutoplay()
				if ( this.touchInter ) {
					clearTimeout(this.touchInter);
					this.touchInter = null
				}
				if ( !this.enableClick ) {
					return
				}
				if ( this.isClickToTouch ) {
					return
				}
				this.isClickToTouch = true
				if ( this.touchTime < 300 && (Math.abs(this.touchmoveX - this.touchmoveX) <= 50 || Math.abs(this.touchmoveY - this.touchmoveY) <= 50) ) {
					let left = 0
					let top = 0
					if ( this.clickOption.left == 'auto' ) {
						left = (this.windowWidth / 2) - (this.clickOption.width / 2)
					} else if ( typeof this.clickOption.left == 'number' ) {
						left = this.clickOption.left
					} else {
						return
					}
					if ( this.clickOption.top == 'auto' ) {
						top =  (this.windowHeight / 2) - (this.clickOption.height / 2)
					} else if ( typeof this.clickOption.top == 'number' ) {
						top = this.clickOption.top
					} else {
						return
					}
					let right = left + this.clickOption.width
					let bottom = top + this.clickOption.height
					if ( this.touchstartX >= left && this.touchstartX <= right && this.touchstartY >= top && this.touchstartY <= bottom ) {
						this.$emit('clickTo')
					}
				}
				setTimeout(() => {
					this.isClickToTouch = false
				}, 50)
			},
			resetTouch () {
				this.touchstartX = 0
				this.touchstartY = 0
				this.touchmoveX = 0
				this.touchmoveY = 0
				this.touchTime = 0
			},
			customClick (e) {
				this.$emit(e.name, ...e.args)
			},
			setCatalog (e) {
				this.$emit('setCatalog', e);
			},
			//初始化
			async init (data) {
				this.clearRefreshTimer()
				await this.getComputedTextSize()
				if ( !this.noChapter ) {
					this.contents = data.contents;
					this.initLoading = true;
					this.resetPage({
						start: parseInt(data.start || 0),
						currentChapter: parseInt(data.currentChapter >= 0 ? data.currentChapter : 1)
					})
				} else {
					this.computedNochapter(data);
				}
			},
			//重计算
			refresh () {
				this.stopAutoplay()
				this.clearRefreshTimer()
				if ( this.isRefreshing ) {
					this.refreshTimer = setTimeout(() => {
						this.refresh()
					}, 100)
					return
				}
				this.isRefreshing = true
				this.resetPage({
					start: this.pageInfo.start,
					currentChapter: this.pageInfo.chapter
				})
			},
			_emitPageInfo (pageInfo, pages) {
				this.isRefreshing = false
				this.$emit('change', pageInfo, pages)
			},
			_reload () {
				this.initLoading = true
				if ( this.loadchapter > -1 ) {
					this.$emit('loadmore', parseInt(this.loadchapter), (status, content) => {
						this.initLoading = false
						if (status == 'success') {
							this._resetReload()
							const index = this.contents.findIndex(item => item.chapter == content.chapter)
							if (index > -1) {
								this.contents[index] = content
							} else {
								this.contents.push(content)
							}
							this.resetPage({
								start: this.loadstart || 0,
								currentChapter: this.loadchapter
							})
						} else {
							this.loadstatus = status
						}
					})
				}
			},
			_resetReload () {
				this.loadstatus = '';
				this.loadchapter = -1;
				this.loadstart = -1;
			},
			//跳转
			change (data) {
				this.stopAutoplay()
				this.clearRefreshTimer()
				this._resetReload()
				if ( data.contents && data.contents.length > 0 ) {
					data.contents.forEach(item => {
						let index = this.contents.findIndex(content => content.chapter == item.chapter)
						if (index > -1) {
							this.contents[index] = item;
						} else {
							this.contents.push(item);
						}
					})
				}
				let index = this.contents.findIndex(content => content.chapter == data.currentChapter)
				if ( index > -1 ) {
					this.initLoading = true;
					this.resetPage({
						start: parseInt(data.start || 0),
						currentChapter: parseInt(data.currentChapter || 1)
					})
				} else {
					if ( this.noChapter ) {
						uni.showToast({
							title: '未找到该章节',
							icon: 'none'
						})
					} else {
						this.initLoading = true;
						this.$emit('loadmore', parseInt(data.currentChapter), (status, content) => {
							this.initLoading = false
							if (status == 'success') {
								const index = this.contents.findIndex(item => item.chapter == content.chapter)
								if (index > -1) {
									this.contents[index] = content
								} else {
									this.contents.push(content)
								}
								this.resetPage({
									start: parseInt(data.start || 0),
									currentChapter: parseInt(data.currentChapter || 1)
								})
							} else {
								this.loadstatus = status;
								this.loadstart = parseInt(data.start || 0)
								this.loadchapter = parseInt(data.currentChapter || 1);
							}
						})
					}
				}
			},
			//翻往上一页
			pagePrev () {
				this.stopAutoplay()
				if ( this.options.pageType != 'scroll' ) {
					this.pagePrevFlip()
				} else {
					this.scrollPrev()
				}
			},
			//翻往下一页
			pageNext () {
				this.stopAutoplay()
				if ( this.options.pageType != 'scroll' ) {
					this.pageNextFlip()
				} else {
					this.scrollNext()
				}
			},
			startAutoplay () {
				if ( this.autoplay && this.pages.length > 0 && this.pages.findIndex(page => page.dataId == this.currentDataId) < this.pages.length - 1 ) {
					this.stopAutoplay()
					this.autoplayTimer = setTimeout(() => {
						this.pageNext()
					}, this.autoplayTime)
				}
			},
			stopAutoplay () {
				if ( this.autoplayTimer ) {
					clearTimeout(this.autoplayTimer)
					this.autoplayTimer = null
				}
			},
			clearRefreshTimer () {
				if ( this.refreshTimer ) {
					clearTimeout(this.refreshTimer)
					this.refreshTimer = null
				}
			},
			initFont () {
				this.fontFace.forEach(font => {
					// #ifndef APP-NVUE
					uni.loadFontFace({
						family: font.fontFamily,
						source: 'url("' + font.src + '")',
						fail (err) {
							console.log(err);
						}
					})
					// #endif
					// #ifdef APP-NVUE
					uni.requireNativePlugin('dom').addRule('fontFace', {
					    fontFamily: font.fontFamily,
						src: "url('" + font.src + "')"
					})
					// #endif
				})
			}
		},
		watch: {
			pageType (newVal, oldVal) {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			fontSize () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			lineHeight () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			slide () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			topGap () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			bottomGap () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			firstTipUnable () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			lastTipUnable () {
				this.$nextTick(function () {
					this.refresh()
				})
			},
			fontFamily () {
				this.$nextTick(async function () {
					await this.getComputedTextSize()
					this.refresh()
				})
			},
			fontFace () {
				this.initFont()
			}
		}
	}
</script>

<!-- #ifdef H5 || APP-VUE -->
<script lang="renderjs" type="module" module="flipPage">
	export default {
		mounted() {
			window.triggerCustomClick = (name, args) => {
				// #ifndef H5
				this.$ownerInstance.callMethod('customClick', {
					name: name,
					args: args
				});
				// #endif
				// #ifdef H5
				this.customClick({
					name: name,
					args: args
				});
				// #endif
			}
		}
	}
</script>
<!-- #endif -->

<style scoped>
	@import url(../modules/computed/computed.css);
	@import url(../modules/flip/flip.css);
	@import url(../modules/scroll/scroll.css);
	.yingbing-read-page {
		/* #ifndef APP-NVUE */
		width: 100%;
		height: 100%;
		/* #endif */
		/* #ifdef APP-NVUE */
		flex: 1;
		/* #endif */
		position: relative;
	}
	.yingbing-loading {
		position: absolute;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
		/* #ifndef APP-NVUE */
		box-sizing: border-box;
		overflow: hidden;
		display: flex;
		/* #endif */
		flex-direction: row;
		align-items: center;
		justify-content: center;
	}
	.yingbing-loading .error-text {
		font-size: 20px;
	}
	.yingbing-slot {
		/* #ifndef APP-NVUE */
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		overflow: hidden;
		/* #endif */
		flex: 1;
	}
</style>